This is a beta version of the Tutorials. Please report any issues or request new tutorial on the GitHub repository.

Interacting with Metadata#

This tutorial walks through the process of interacting with metadata samples from CAD1. However, the same process can be applied to other challenges.

from pprint import pprint

Obtaining the sample data#

In order to demonstrate basic functionality, we will download a small demo dataset for CAD1.

!gdown 10SfuZR7yVlVO6RwNUc3kPeJHGiwpN3VS
!tar -xvf cadenza_data_demo.tar.xz
^C
Traceback (most recent call last):
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/bin/gdown", line 8, in <module>
    sys.exit(main())
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/gdown/cli.py", line 163, in main
    download(
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/gdown/download.py", line 157, in download
    res = sess.get(url, stream=True, verify=verify)
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/requests/adapters.py", line 667, in send
    resp = conn.urlopen(
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/urllib3/connectionpool.py", line 789, in urlopen
    response = self._make_request(
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/urllib3/connectionpool.py", line 536, in _make_request
    response = conn.getresponse()
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/site-packages/urllib3/connection.py", line 464, in getresponse
    httplib_response = super().getresponse()
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/http/client.py", line 1375, in getresponse
    response.begin()
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/http/client.py", line 318, in begin
    version, status, reason = self._read_status()
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/http/client.py", line 279, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/socket.py", line 705, in readinto
    return self._sock.recv_into(b)
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/ssl.py", line 1307, in recv_into
    return self.read(nbytes, buffer)
  File "/home/gerardoroadabike/anaconda3/envs/clarity39/lib/python3.10/ssl.py", line 1163, in read
    return self._sslobj.read(len, buffer)
KeyboardInterrupt
tar: cadenza_data_demo.tar.xz: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

The Structure of the metadata#

In CAD1, there are two metadata files, which are JSON files. This structure is similar across all challenges. Some challenges may have additional metadata files.

  • listeners.json - listeners’ characteristics in form of audiograms for left and right ear.

  • musdb18hq.json - list of audio tracks to process.

Dataset

Structure

Index

listener

dict of dicts

LISTENER_ID

musdb18hq

list of dict

Track Name


Reading the metadata files#

The challenges metadata are stored in JSON format. The python’s JSON library imports JSON files and parses them into python objects. This is demonstrated in the cell below.

import json

with open("cadenza_data_demo/cad1/task1/metadata/listeners.valid.json") as f:
    listeners = json.load(f)

with open("cadenza_data_demo/cad1/task1/metadata/musdb18.valid.json", "r", encoding="utf-8") as file:
    song_data = json.load(file)

Listeners#

The next cell shows two samples of listeners from the validation set. These are anonymized real audiograms.

  • audiogram_cfs is a list of center frequencies in Hz.

  • auidogram_levels_l and audiogram_levels_r are lists of hearing thresholds in dB SPL for the left and right ear, respectively.

  • name is the listener’s id.

pprint(listeners)
{'L5040': {'audiogram_cfs': [250, 500, 1000, 2000, 3000, 4000, 6000, 8000],
           'audiogram_levels_l': [30, 25, 25, 70, 80, 80, 80, 80],
           'audiogram_levels_r': [20, 15, 20, 45, 55, 70, 80, 80],
           'name': 'L5040'},
 'L5076': {'audiogram_cfs': [250, 500, 1000, 2000, 3000, 4000, 6000, 8000],
           'audiogram_levels_l': [15, 20, 30, 30, 45, 50, 60, 75],
           'audiogram_levels_r': [15, 25, 30, 35, 40, 40, 60, 70],
           'name': 'L5076'}}

Music#

The next cell shows one samples of music tracks from the validation set. This file contains general information about the track like the name, split and licence.

pprint(song_data)
[{'Genre': 'Pop/Rock',
  'License': 'Restricted',
  'Source': 'DSD',
  'Split': 'valid',
  'Track Name': 'Actions - One Minute Smile'}]

Let’s load a 30-second sample of the mixture signal from the first song in the validation set.

import pandas as pd
from IPython.display import Audio
from pathlib import Path
from scipy.io import wavfile

# Load song_data as pandas DataFrame
songs_valid = pd.DataFrame.from_dict(song_data)
split_directory = (
    "test"
    if songs_valid.loc[0, "Split"] == "test"
    else "train"
    )

sample_rate, mixture_signal = wavfile.read(
        Path('cadenza_data_demo/cad1/task1/audio/musdb18hq')
        / split_directory
        / songs_valid.loc[0, "Track Name"]
        / "mixture.wav"
)

# Take only 30 seconds
mixture_signal = mixture_signal[30*sample_rate:60*sample_rate, :]
Audio(mixture_signal.T, rate=sample_rate)